﻿using MailKit.Net.Smtp;
using MimeKit;
using MKAdmin.DTO.Web.Common;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Configuration;

namespace MKAdmin.ToolKit
{
    public class EmailHelper
    {
        #region 发送邮件

        /// <summary>
        /// 邮件服务器
        /// </summary>
        private static MailHost _mailHost;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        static EmailHelper()
        {
            // 读取邮件服务器配置
            var section = ConfigurationManager.GetSection("system.net/mailSettings/smtp") as SmtpSection;

            _mailHost = new MailHost
            {
                Host = section.Network.Host,
                Port = section.Network.Port,
                UserName = section.Network.UserName,
                Password = section.Network.Password,
                EnableSsl = section.Network.EnableSsl,
                DisplayName = section.From
            };
        }

        /// <summary>
        /// 作者：
        /// 时间：2018.01.09
        /// 描述：邮件发送业务
        /// </summary>
        /// <param name="emailInfo">邮件信息</param>
        /// <returns></returns>
        public static Result Send(MailInfo mailInfo)
        {
            var result = new Result();

            // 邮件服务器验证
            if (string.IsNullOrWhiteSpace(_mailHost.Host) || string.IsNullOrWhiteSpace(_mailHost.UserName) || string.IsNullOrWhiteSpace(_mailHost.Password))
            {
                result.status = false;
                result.msg = "邮件服务器配置失败";
            }
            // 邮件信息验证
            else if (null == mailInfo.To || !mailInfo.To.Any() || string.IsNullOrWhiteSpace(mailInfo.Body))
            {
                result.status = false;
                result.msg = "邮件信息验证失败";
            }
            else
            {
                var message = MimeMessageBuild(mailInfo);
                result = Send(message, mailInfo.Async);
            }

            return result;
        }

        /// <summary>
        /// 作者：
        /// 时间：2018.06.04
        /// 描述：邮件发送
        /// </summary>
        /// <param name="message">邮件信息</param>
        /// <param name="async">是否异步</param>
        /// <param name="userNames">发件人列表</param>
        /// <param name="fromIndex">发件人索引</param>
        /// <param name="reSendTimes">重发次数</param>
        private static Result Send(MimeMessage message, bool async)
        {
            var result = new Result();
            // 发件人
            message.From.Clear();
            message.From.Add(new MailboxAddress(_mailHost.DisplayName, _mailHost.UserName));

            using (var client = new SmtpClient())
            {
                try
                {
                    // 接受所有的SSL证书(以防服务器支持STARTTLS)
                    client.ServerCertificateValidationCallback = (s, c, h, e) => true;
                    // 连接邮件服务器
                    client.Connect(_mailHost.Host, _mailHost.Port, _mailHost.EnableSsl);
                    // 或
                    // client.Connect(_mailHost.Host, _mailHost.Port, SecureSocketOptions.SslOnConnect);
                    // 由于我们没有OAuth2令牌，因此禁用XOAUTH2身份验证机制
                    client.AuthenticationMechanisms.Remove("XOAUTH2");
                    // 只有在SMTP服务器需要身份验证时才需要
                    client.Authenticate(_mailHost.UserName, _mailHost.Password);

                    // 邮件发送(同步异步)
                    if (async)
                    {
                        var task = client.SendAsync(message);
                        task.Wait();
                    }
                    else client.Send(message);

                    result.status = true;
                    result.msg = "发送成功";
                }
                catch (Exception ex)
                {
                    result.status = false;
                    result.msg = "发送异常";
                    LogHelper.Error("邮件发送失败", ex);
                }
                finally
                {
                    client.Disconnect(true);
                }

                return result;
            }
        }

        /// <summary>
        /// 作者：
        /// 时间：2018.06.04
        /// 描述：邮件信息构建
        /// </summary>
        /// <param name="mailInfo"></param>
        /// <returns></returns>
        private static MimeMessage MimeMessageBuild(MailInfo mailInfo)
        {
            // 实例化邮件信息并设置标题
            var message = new MimeMessage { Subject = mailInfo.Subject };

            // 收件人
            mailInfo.To.ForEach(to =>
            {
                if (!string.IsNullOrWhiteSpace(to)) message.To.Add(new MailboxAddress(to));
            });
            // 抄送人
            mailInfo.Cc?.ForEach(cc =>
            {
                if (!string.IsNullOrWhiteSpace(cc)) message.To.Add(new MailboxAddress(cc));
            });

            // 实例化邮件主体
            var bodyBuilder = new BodyBuilder();

            if (mailInfo.IsBodyHtml) bodyBuilder.HtmlBody = mailInfo.Body; // html主体
            else bodyBuilder.TextBody = mailInfo.Body;  // text主体

            // 邮件附件
            mailInfo.Attachments?.ForEach(attachment =>
            {
                if (!string.IsNullOrWhiteSpace(attachment)) bodyBuilder.Attachments.Add(attachment);
            });

            message.Body = bodyBuilder.ToMessageBody();

            return message;
        }

        /// <summary>
        /// 作者：
        /// 时间：2018.06.04
        /// 描述：邮件信息
        /// </summary>
        public class MailInfo
        {
            public MailInfo()
            {
                To = new List<string>();
                Cc = new List<string>();
            }

            /// <summary>
            /// 收件者
            /// </summary>
            public List<string> To { get; set; }

            /// <summary>
            /// 抄送者
            /// </summary>
            public List<string> Cc { get; set; }

            /// <summary>
            /// 标题
            /// </summary>
            public string Subject { get; set; }

            /// <summary>
            /// 内容
            /// </summary>
            public string Body { get; set; }

            /// <summary>
            /// 邮件正文是否为 Html 格式的值
            /// </summary>
            public bool IsBodyHtml { get; set; }

            /// <summary>
            /// 附件绝对路径列表
            /// </summary>
            public List<string> Attachments { get; set; }

            /// <summary>
            /// 是否异步发送
            /// </summary>
            public bool Async { get; set; }
        }

        /// <summary>
        /// 作者：
        /// 时间：2018.06.04
        /// 描述：邮件服务端
        /// </summary>
        public class MailHost
        {
            /// <summary>
            /// 邮件服务器主机
            /// </summary>
            public string Host { get; set; }

            /// <summary>
            /// 邮件服务器端口
            /// </summary>
            public int Port { get; set; }

            /// <summary>
            /// 邮件发送者
            /// </summary>
            public string UserName { get; set; }

            /// <summary>
            /// 邮件发送者密码
            /// </summary>
            public string Password { get; set; }

            /// <summary>
            /// 指定的显示名和地址信息构成的显示名
            /// </summary>
            public string DisplayName { get; set; }

            /// <summary>
            /// 使用安全套接字层
            /// </summary>
            public bool EnableSsl { get; set; }
        }

        #endregion
    }
}
